package idv.cjcat.signals.tests.cases {
	import idv.cjcat.signals.ISignal;
	import idv.cjcat.signals.Signal;
	
	public class SignalTest extends CJSignalsTestCase {
		
		public function SignalTest(testMethod:String = null) {
			super(testMethod);
		}
		
		private var _int:int;
		private var _string:String;
		private var _flag:Boolean;
		
		override protected function tearDown():void {
			_string = null;
		}
		
		public function testValueClasses():void {
			var s:ISignal;
			var f:Function;
			
			//test listener invocation
			//-------------------------------------------------
			
			s = new Signal(int, String);
			f = function(a:int, b:String):void {
				_int = a;
				_string = b;
			};
			s.add(f);
			s.dispatch(1, "abc");
			assertEquals(1, _int);
			assertEquals("abc", _string);
			s.clear();
			
			
			//test invalid argument number
			//-------------------------------------------------
			
			try {
				f = function():void {};
				s.add(f);
				assertTrue(false);
			} catch (e:ArgumentError) {
				assertTrue(true);
			}
			
			
			//test invalid argument types
			//-------------------------------------------------
			
			try {
				s.dispatch("cba", 2);
				assertTrue(false);
			} catch (e:ArgumentError) {
				assertTrue(true);
				assertEquals(1, _int);
				assertEquals("abc", _string);
			}
			
			
			//test addOnce()
			//-------------------------------------------------
			
			f = function(a:int, b:String):void {}
			s.clear();
			s.add(f);
			assertEqualsArray([f], s.listeners);
			s.remove(f);
			assertEqualsArray([], s.listeners);
			s.addOnce(f);
			assertEqualsArray([f], s.listeners);
			s.dispatch(1, "abc");
			assertEqualsArray([], s.listeners);
		}
		
		public function testListeners():void {
			
			//test value classes array
			//-------------------------------------------------
			
			var s:ISignal = new Signal(int);
			assertEqualsArray([int], s.valueClasses);
			
			
			//test listeners getter
			//-------------------------------------------------
			
			var f1:Function = function(i:int):void {};
			var f2:Function = function(i:int):void {};
			var f3:Function = function(i:int):void {};
			var f4:Function = function(i:int):void {};
			var f5:Function = function(i:int):void {};
			s.add(f1);
			s.add(f2);
			s.add(f3);
			s.add(f4);
			s.add(f5);
			assertEqualsArray([f1, f2, f3, f4, f5], s.listeners);
			
			
			//test listener priority
			//-------------------------------------------------
			
			s.clear();
			s.add(f1, 0);
			s.add(f2, 1);
			s.add(f3, 1);
			s.add(f4, 2);
			s.add(f5, 2);
			assertEqualsArray([f4, f5, f2, f3, f1], s.listeners);
			
			s.remove(f2);
			assertEqualsArray([f4, f5, f3, f1], s.listeners);
			
			
			//test getPriority() for non-listener
			//-------------------------------------------------
			
			assertEquals(1, s.getPriority(f3));
			assertTrue(isNaN(s.getPriority(f2)));
			
			
			//test listener list cloning during dispatch
			//-------------------------------------------------
			
			var f6:Function = function(i:int):void {};
			var f7:Function = function(i:int):void {};
			var f8:Function = function(i:int):void {
				s.add(f6);
				assertEqualsArray([f7, f8], s.listeners);
				s.remove(f7);
				assertEqualsArray([f7, f8], s.listeners);
			};
			
			s.clear();
			s.add(f7);
			s.add(f8);
			assertEqualsArray([f7, f8], s.listeners);
			s.dispatch(0);
			assertEqualsArray([f8, f6], s.listeners);
		}
	}
}